﻿using UnityEngine;

namespace Miao
{
    /// <summary>
    /// 提供对角度的支持
    /// </summary>
    public class AngleUtility
    {
        /// <summary>
        /// 将值域为 [-∞, +∞] 的 <paramref name="angle"/> 转为值域为 [0, 360] 的角度
        /// </summary>
        public static float GetStandardAngle(float angle)
        {
            angle %= 360f;
            return angle < 0f ? angle + 360f : angle;
        }
        /// <summary>
        /// 判断顺时针角度 <paramref name="angle"/> 与顺时针角度 <paramref name="targetAngle"/> 的相对位置.
        /// 角度范围[0f, 360f]
        /// </summary>
        /// <returns>如果位于 <paramref name="targetAngle"/> 左侧, 返回 -1, 位于 <paramref name="targetAngle"/>右侧, 返回 1, 同向返回 0</returns>
        public static float AngleDirection(float angle, float targetAngle)
        {
            return MathW.SignZero(DeltaAngle(angle, targetAngle));
        }
        /// <summary>
        /// 获取角度 <paramref name="angle"/> 到 角度<paramref name="targetAngle"/> 的最短差.
        /// 角度范围[0f, 360f]
        /// </summary>
        /// <returns>两者之间的最短角度(带符号)</returns>
        public static float DeltaAngle(float angle, float targetAngle)
        {
            angle = MathW.Repeat(angle - targetAngle, 360f);//两个角度相减并限制在360°
            if (angle > 180f) angle -= 360f;//比例朝向折算
            return angle;
        }
        /// <summary>
        /// 将顺时针方向值域为[0f, 360f] 的角度 <paramref name="fullAngle"/> 转为 [-180f, 180f] 的带符号角度
        /// </summary>
        public static float FullAngleToSignedAngle(float fullAngle)
        {
            if (fullAngle > 180f) return fullAngle - 360f;
            return fullAngle;
        }
        /// <summary>
        /// 将值域为 [-180, 180] 的角度转为 值域为 [0, 360] 的角度.
        /// 角度均以逆时针为正
        /// </summary>
        public static float SignedAngleToFullAngle(float signedAngle)
        {
            if (signedAngle < 0f) return signedAngle + 360f;
            return signedAngle;
        }

        /// <summary>
        /// 对角度进行平滑阻尼
        /// </summary>
        public static Quaternion SmoothDamp(Quaternion current, Quaternion target, ref float currentVelocity, float smoothTime)
        {
            return Quaternion.Slerp(current, target, Mathf.SmoothDampAngle(0f, 1f, ref currentVelocity, smoothTime));
        }
    }
}